#include "rwip.h" // RW SW initialization
#include "co_debug.h"
#include "app.h"
#include "peripheral.h"
#include "co_debug.h"

#include "device.h"
#include "component.h"
#include "debug_config.h"

#define TSM12_LOG(format, ...) __OSAL_LOG("[TSM12.c] " C_GREEN format C_NONE"\r\n", ##__VA_ARGS__)

#define TSM_VIRTUALHARDWARE vIIC_8
/*********************************************************************
 * TYPEDEFS
 */
// #define 	DEBUG_TSM
#define TSM_REG_CTRL1 0X08
#define TSM_REG_CTRL2 0X09
#define TSM_REG_SENSITIVITY1 0X02
#define TSM_REG_SENSITIVITY2 0X06
#define TSM_REG_SENSITIVITY3 0X22
#define TSM_REG_ADDR_OUTPUT 0x10
#define TSM_REG_OUTPUT_A 0X10
#define TSM_REG_OUTPUT_B 0X12
#define TSM_REG_OUTPUT_C 0X13
// TSM output register bit
#define TSM_OUTPUT_REG_BIT0 0X03 // 0x01//
#define TSM_OUTPUT_REG_BIT2 0X0C // 0x04//
#define TSM_OUTPUT_REG_BIT4 0X30 // 0x10//
#define TSM_OUTPUT_REG_BIT6 0XC0 // 0x40//

#define TSM_LOCK_MASK_REG 0X3B // For applying MULTI bit(0x09[5]), Lock mask bits should be 8‟h10100101
#define TSM_TOUCH_MODE_REG 0X41 // For applying MULTI bit(0x09[5]), Lock mask bits should be 8‟h10100101 and FEN bit should be 1‟b1

#define TSM_DLY_200MS 200
#define TSM_DLY_50MS 50
#define TOUCH_SLAVE_ADDR (0xD0 >> 1) // 0b11010000
#define TSM_REG_OUTPUT_LEN 4
static uint8_t tsm_reg_init = 0;

#define DEFAULT_VALUE_IO 0x55 // 0x33

#define TSM_SINGLE_OUTPUT_MODE (1 << 5)
#define TSM_MULTIPE_OUTPUT_MODE (0 << 5)

#define TSM_INIT_FAIL_REPEAT_TIMES 3 // 初始化失败重试次数
// data of init TSM12S register
const unsigned char TSM_contrl1[] =
    {
        TSM_REG_SENSITIVITY1, // 首地址 0x02
        0x45,     // 地址0x02 Ch1~Ch2灵敏度
        0x33,     // 地址0x03 Ch3~Ch4灵敏度
};

const unsigned char TSM_contrl2[] =
    {
        TSM_REG_SENSITIVITY2, // 首地址 0x06
        0x39,     // 0x06 Ch5~Ch6灵敏度
        0x43,     // 0x07 Ch7~Ch8灵敏度
        0x08,                 // 0x08 CTRL1,interrupt level is high
        0x07,                 // 0x09 CTRL2
        0x00,                 // 0x0A Ref_rst1
        0x00,                 // 0x0B Ref_rst2
        0x00,                 // 0x0C Ch_hold1
        0x00,                 // 0x0D Ch_hold1
        0x00,                 // 0x0E Cal_hold1
        0x00                  // 0x0F Cal_hold2
};

// data of init TSM12S register
const unsigned char TSM_contrl3[] =
    {
        TSM_REG_SENSITIVITY3, // 首地址 0x22
        0x44,     // 地址0x22 Ch9~Ch10灵敏度
        0x45,     // 地址0x23 Ch11~Ch12灵敏度
};

const unsigned char TSM_contrl_reset[] =
    {
        TSM_REG_CTRL2,
        (0x0F | TSM_SINGLE_OUTPUT_MODE),
};

const unsigned char TSM_contrl_sleep[] =
    {
        TSM_REG_CTRL2,
        0x07,
};

const unsigned char TSM_contrl_wakeup[] =
    {
        TSM_REG_CTRL2,
        (0x03 | TSM_SINGLE_OUTPUT_MODE),
};

const unsigned char TSM_set_touchMode_start[] =
    {
        TSM_LOCK_MASK_REG,
        0xa5,
};

const unsigned char TSM_set_touchMode_apply[] =
    {
        TSM_TOUCH_MODE_REG,
        0x94,
};

const unsigned char TSM_set_touchMode_end[] =
    {
        TSM_LOCK_MASK_REG,
        0x00,
};

static bool TSM_I2C_Write(uint8_t *data, uint8_t len)
{
    return i2c_master_write((uint16_t)TOUCH_SLAVE_ADDR, data, len);
}

static bool TSM_I2C_Read(uint8_t *data, uint8_t len)
{
    return i2c_master_read((uint16_t)TOUCH_SLAVE_ADDR, data, len);
}

/*********************************************************************
 * @fn 	 	 TSM_init
 *
 * @brief	 TMS12 init
 *
 * @param	 none
 *
 * @return  return 1/0
 ************************************************************************/
#define IIC_SPEED_STANDARD_MODE 100000 /* 标准100K */
#define IIC_SPEED_FAST_MODE 400000     /* 快速100K */
#define IIC_SPEED_HIGH_MODE 3400000    /* 高速3.4M */

#define TSM12_RST_PIN vPIN_C38 //
static int TSM_init(void)
{
    Device_Write(vPIN_C38, NULL, 0, 1);
    co_delay_ms(5);
    Device_Write(vPIN_C38, NULL, 0, 0);
    co_delay_ms(10);
    pinmux_config(IIC_SCL_PIN, PINMUX_I2C_MST_SCK_CFG);
    pinmux_config(IIC_SDA_PIN, PINMUX_I2C_MST_SDA_CFG);
    pmu_pin_mode_set((1 << IIC_SDA_PIN) | (1 << IIC_SCL_PIN), PMU_PIN_MODE_OD_PU);
    i2c_open(I2C_MODE_MASTER, IIC_SPEED_STANDARD_MODE);

    if (false == TSM_I2C_Write((uint8_t *)TSM_contrl_reset, sizeof(TSM_contrl_reset)))
    {
        goto err;
    }

    co_delay_ms(1);

    if (false == TSM_I2C_Write((uint8_t *)TSM_contrl1, sizeof(TSM_contrl1)))
    {
        goto err;
    }

    if (false == TSM_I2C_Write((uint8_t *)TSM_contrl2, sizeof(TSM_contrl2)))
    {
        goto err;
    }

    if (false == TSM_I2C_Write((uint8_t *)TSM_contrl3, sizeof(TSM_contrl3)))
    {
        goto err;
    }

    // 设置触摸模式
    if (false == TSM_I2C_Write((uint8_t *)TSM_set_touchMode_start, sizeof(TSM_set_touchMode_start)))
    {
        goto err;
    }

    if (false == TSM_I2C_Write((uint8_t *)TSM_set_touchMode_apply, sizeof(TSM_set_touchMode_apply)))
    {
        goto err;
    }

    if (false == TSM_I2C_Write((uint8_t *)TSM_set_touchMode_end, sizeof(TSM_set_touchMode_end)))
    {
        goto err;
    }


    tsm_reg_init = 1;
    TSM12_LOG("TSM_init OK!!");
    return 0;
err:
    TSM12_LOG("TSM err!!!");
    return -1;
}

/**
 * @brief  TSM12驱动，Read接口
 * @note
 * @param  pCmd：命令
 *         param：参数---还需根据param来添加特征值处理
 *
 * @return SUCCESS   ERROR
 */
static int32_t TSM12_Read(VirtualHardware_enum_t dev, void *data, uint32_t len, uint32_t param)
{
    if (vCAP_SENSE2 == dev)
    {
        if (!tsm_reg_init)
        {
            return -1;
        }
        // uint8_t keystring[16] = {'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S'};
        uint8_t keystring[16] = {'1', '4', '*', '7', 'E', 'F', 'G', 'H', '2', '3', '5', '6', '8', '0', '9', '#'};
        uint8_t readbuf[TSM_REG_OUTPUT_LEN] = {0xaa, 0xaa, 0xaa, 0xaa};
        uint8_t i, keyvalue = 0;
        uint8_t gTsmWriteReg = TSM_REG_ADDR_OUTPUT;
        uint8_t readOutput[TSM_REG_OUTPUT_LEN];
        uint8_t inputData = 0xff;    

        gTsmWriteReg = TSM_REG_ADDR_OUTPUT;
        TSM_I2C_Write((uint8_t *)&gTsmWriteReg, 1);
        TSM_I2C_Read(readbuf, TSM_REG_OUTPUT_LEN);
        for (i = 0; i < 16; i++)
        {
            inputData = readbuf[i / 4] >> ((i % 4) * 2);
            if (inputData & 0x01 == 0x01 || inputData & 0x02 == 0x02)
            {
                keyvalue = keystring[i];
                TSM12_LOG("data %d vol:%c----index:%d\r\n", inputData, keyvalue,i);
            }

            if ((readbuf[i / 4] >> ((i % 4) * 2) & 0x03) == 0x03)
            {
                keyvalue = keystring[i]; // ok
                *(uint8_t *)data = keyvalue;
            //    TSM12_LOG("TSM12 vol:%c----index:%d\r\n", keyvalue,i);
            }
        }
    }
    return 0;
}

static int8_t TSM12_Disable(VirtualHardware_enum_t dev)
{
    if (vCAP_SENSE2 == dev)
    {
        if (!tsm_reg_init)
        {
            return -1;
        }
        TSM12_LOG("TSM12_Disable \r\n");
        TSM_I2C_Write((uint8_t *)TSM_contrl_sleep, sizeof(TSM_contrl_sleep));
    }

    return 0;
}

static int8_t TSM12_Enable(VirtualHardware_enum_t dev)
{
    if (vCAP_SENSE2 == dev)
    {
        if (!tsm_reg_init)
        {
            return -1;
        }
        TSM12_LOG("TSM12_Enable \r\n");
        i2c_open(I2C_MODE_MASTER, IIC_SPEED_STANDARD_MODE);

        if (false == TSM_I2C_Write((uint8_t *)TSM_contrl_wakeup, sizeof(TSM_contrl_wakeup)))
        {
            TSM12_LOG("TSM_I2C_Write 1\r\n");
            // 如果失败 再写一次
            TSM_I2C_Write((uint8_t *)TSM_contrl_wakeup, sizeof(TSM_contrl_wakeup));
            TSM12_LOG("TSM_I2C_Write 2\r\n");
        }//

        // 设置触摸模式  单点或多点
        // TSM_I2C_Write((uint8_t *)TSM_set_touchMode_start, sizeof(TSM_set_touchMode_start));
        // TSM_I2C_Write((uint8_t *)TSM_set_touchMode_apply, sizeof(TSM_set_touchMode_apply));
        // TSM_I2C_Write((uint8_t *)TSM_set_touchMode_end, sizeof(TSM_set_touchMode_end));

    }

    return 0;
}
/**
 * @brief TSM12设备初始化
 *
 *
 * @note
 */
static void TSM12_Init(void)
{
    TSM12_LOG("TSM12 init");
    /* gpio初始化 */
    uint8_t initfailCnt = 0;
    while(initfailCnt < TSM_INIT_FAIL_REPEAT_TIMES)
    {
        initfailCnt++;
        if (TSM_init() == 0)
        {
            initfailCnt = 0;
            // 初始化成功
            break;
        }
    }
    Device_stu_t *dcb = Device_GetDeviceCtrlBlock(vCAP_SENSE);
    dcb->read = TSM12_Read;
    dcb->disable = TSM12_Disable;
    dcb->enable = TSM12_Enable;
}
INIT_DEVICE_EXPORT(TSM12_Init);
